package jobascjp;

class Bird {

    {
        System.out.println("b1 "); // nach super()
    } // IB

    public Bird() {
        // super()
        // Instanz-Initblock
        System.out.println("b2 ");
    }
}

class Raptor extends Bird {

    static {
        // Static-Initblock - 1
        System.out.println("r1 ");
    }

    public Raptor() {
        // super()
        // Instanz-Initblock
        System.out.println("r2 ");
    }

    {
        System.out.println("r3 "); // Instanz-Initblock
    }

    static {
        System.out.println("r4 "); // Static-Initblock - 2
    }
}

class Hawk extends Raptor {

    public static void main(String[] args) {
        System.out.println("pre ");
        new Hawk();
        System.out.println("hawk ");
        
        /*
         * What is the result?
         * 
         * pre b1 b2 r3 r2 hawk
         * pre b2 b1 r2 r3 hawk
         * pre b2 b1 r2 r3 hawk r1 r4
         * r1 r4 pre b1 b2 r3 r2 hawk // korrekt!
         * r1 r4 pre b2 b1 r2 r3 hawk
         * pre r1 r4 b1 b2 r3 r2 hawk
         * pre r1 r4 b2 b1 r2 r3 hawk
         * The order of output cannot be predicted.
         * Compilation fails.
         * 
         * Anmerkungen: 
         * Statische Initialisierungs-Bloecke werden zur Ladezeit ausgewertet.
         * Instanz-Initialisierungs-Bloecke direkt nach dem super()-Call.
         * Wie gehts nun los: Klassenlader laedt Klassen unter anderem Raptor,
         * dann kommen die beiden statischen Bloecke hier r1, r4 gemaess 
         * Quelltext-Reihenfolge. Es gibt nun keine statischen Bloecke mehr und
         * es wird nach main() geschaut. In main() wird dann Hawk() angelegt,
         * also Hawk-Konstruktor; es gibt keinen, also Default-Konstruktor, also
         * super() zu Beginn, wir sind in Raptor(); In Raptor steht auch super(),
         * wir sind Bird(), in Bird() gibt es kein super(), aber einen Block,
         * also Ausgabe Block, Bird-Konstruktor also b1, b2; dann runter in 
         * Raptor, erst Block dann Konstruktor, also r3, r2; dann main()-Ende 
         * Hawk, wir haben: r1, r4, pre, b1, b2, r3, r2, hawk!
         */
    }
}
